package com.zxc.realm;

import com.zxc.entity.SysUser;
import com.zxc.service.SysUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AuthRealm extends AuthorizingRealm {

    @Autowired
    private SysUserService sysUserService;

    //授权方法
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
          //根据用户的编号，从数据库中，加载该用户的身份信息，或者是拥有的权限列表
        //1、通过principals获得用户的信息--------------即为认证方法返回的结果中的第一个参数（map）
        Map map = (Map) principals.getPrimaryPrincipal();

        //2、取得用户的id
        SysUser sysUser = (SysUser) map.get("sysUser");
        Long userId = sysUser.getUserId();

        //3、根据id加载权限菜单 和 用户角色权限
        List<Map> menuList = sysUserService.loadMenu(Math.toIntExact(userId));

        //1)、permission
        List<String> permission = new ArrayList();
        List<Map> permissionList = sysUserService.loadPermission(Math.toIntExact(userId));
        for (Map map1 : permissionList){
            permission.add((String) map1.get("percode"));
        }
        //2)、menu
        List<String> menu = new ArrayList<>();
        for (Map map1 : menuList){
            menu.add((String) map1.get("name"));
        }

        //4、创建AuthorizationInfo对象，封装所有角色或者是权限信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permission);//加载权限列表
        info.addRoles(menu);//加载用户角色
        return info;
    }

    //认证方法
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("@@@@@@@@@@@@@进入认证方法==========");
        String principal = (String) token.getPrincipal();
        Map map = new HashMap();

        Map userMap = sysUserService.login(principal);
        if (userMap == null){
            return null;
        }

        //得到用户id
        Integer userId = (Integer) userMap.get("user_id");
        List<Map> mapList = sysUserService.loadMenu(userId);

        SysUser sysUser = new SysUser();
        sysUser.setUserId(((Integer) userMap.get("user_id")).longValue());
        sysUser.setLocked((Integer) userMap.get("locked"));
        sysUser.setUserName((String) userMap.get("user_name"));
        sysUser.setUserCode((String) userMap.get("user_code"));
        sysUser.setUserPassword((String) userMap.get("user_password"));

        //用户对应的角色
        String sysUserRole = (String) userMap.get("name");

        //存放用户信息
        map.put("sysUser",sysUser);
        //存放用户权限信息
        map.put("menuList",mapList);
        //存放用户对应的角色
        map.put("sysUserRole",sysUserRole);

        String pwd = sysUser.getUserPassword();
        String accp = "accp";
        AuthenticationInfo info = new SimpleAuthenticationInfo(map,pwd, ByteSource.Util.bytes(accp),"myRealm");
        return info;
    }
}
